#ifndef _RAFFLEACTIVITY_H_
#define _RAFFLEACTIVITY_H_

#include "State.h"

class RaffleActivity;

class CanRaffleState : public State
{
public:
    CanRaffleState(RaffleActivity* activity);

    void DeductMoney() override;
    bool Raffle() override;
    void DispensePrize() override;
private:
    RaffleActivity* _activity;
};

class DispenseOutState : public State
{
public:
    DispenseOutState(RaffleActivity* activity);
    void DeductMoney() override;
    bool Raffle() override;
    void DispensePrize() override;
private:
    RaffleActivity* _activity;
};

class DispenseState : public State
{
public:
    DispenseState(RaffleActivity* activity);
    void DeductMoney() override;
    bool Raffle() override;
    void DispensePrize() override;
private:
    RaffleActivity* _activity;
};

class NoRaffleState : public State
{
public:
    NoRaffleState(RaffleActivity* activity);
    void DeductMoney() override;
    bool Raffle() override;
    void DispensePrize() override;
private:
    RaffleActivity* _activity;
};

class RaffleActivity
{
public:
    RaffleActivity(int count) {
        _state = GetNoRaffleState();
        _count = count;
    }

    State* GetState() const {
        return _state;
    }

    void SetState(State* const state) {
        _state = state;
    }

    int GetCount() {
        return _count--;
    }

    void SetCount(const int count) {
        _count = count;
    }

    State* GetNoRaffleState() const {
        return _noRaffleState;
    }

    void SetNoRaffleState(State* const noRaffleState) {
        _noRaffleState = noRaffleState;
    }

    State* GetCanRaffleState() const {
        return _canRaffleState;
    }

    void SetCanRaffleState(State* const canRaffleState) {
        _canRaffleState = canRaffleState;
    }

    State* GetDispenseState() {
        return _dispenseState;
    }

    void SetDispenseState(State* const dispenseState) {
        _dispenseState = dispenseState;
    }

    State* GetDispenseOutState() const {
        return _dispenseOutState;
    }

    void SetDispenseOutState(State* const dispenseOutState) {
        _dispenseOutState = dispenseOutState;
    }

    void DeductMoney() {
        _state->DeductMoney();
    }

    void Raffle() {
        if (_state->Raffle()) {
            _state->DispensePrize();
        }
    }


private:
    State* _state = nullptr;
    int _count = 0;
    State* _noRaffleState = new NoRaffleState(this);
    State* _canRaffleState = new CanRaffleState(this);
    State* _dispenseState = new DispenseState(this);
    State* _dispenseOutState = new DispenseOutState(this);
};

#endif // _RAFFLEACTIVITY_H_